﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Collections.Generic;
using OfficeOpenXml;
using System.IO;



namespace AutoCAD.Net48
{
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.EditorInput;
    using System.Collections.Generic;

    public class TableToExcelCommand
    {
        /// <summary>
        /// 自动合并
        /// </summary>
        [CommandMethod("MergeTableToExcel")]
        public void MergeTableToExcel()
        {
            TableExtractor extractor = new TableExtractor();
            List<CellData> tableContents = extractor.ExtractTableContents_AutoMerge();

            if (tableContents.Count > 0)
            {
                ExcelExporter exporter = new ExcelExporter();
                string filePath = "C:\\Users\\Administrator\\Desktop\\MergeTableToExcel.xlsx";
                exporter.ExportToExcel_AutoMerge(tableContents, filePath);

                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nTable exported to {filePath}");
            }
            else
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nNo table selected or table is empty.");
            }
        }

        /// <summary>
        /// 只有第一列跨列
        /// </summary>

        [CommandMethod("TableToExcel")]
        public void TableToExcel()
        {
            TableExtractor extractor = new TableExtractor();
            List<List<string>> tableContents = extractor.ExtractTableContents();

            if (tableContents.Count > 0)
            {
                ExcelExporter exporter = new ExcelExporter();
                string filePath = "C:\\Users\\Administrator\\Desktop\\TableToExcel.xlsx";
                exporter.ExportToExcel(tableContents, filePath);

                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"\nTable exported to {filePath}");
            }
            else
            {
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nNo table selected or table is empty.");
            }
        }
    }

    public class TableExtractor
    {
        /// <summary>
        /// 自动合并
        /// </summary>
        /// <returns></returns>    
        public List<CellData> ExtractTableContents_AutoMerge()
        {
            List<CellData> tableContents = new List<CellData>();
            HashSet<string> processedCells = new HashSet<string>();

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a table: ");
            peo.SetRejectMessage("\nSelected entity is not a table.");
            peo.AddAllowedClass(typeof(Table), true);

            PromptEntityResult per = ed.GetEntity(peo);

            if (per.Status == PromptStatus.OK)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Table table = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Table;

                    if (table != null)
                    {
                        for (int r = 0; r < table.Rows.Count; r++)
                        {
                            for (int c = 0; c < table.Columns.Count; c++)
                            {
                                if (processedCells.Contains($"{r},{c}"))
                                {
                                    continue;
                                }

                                Cell cell = table.Cells[r, c];
                                if (cell.IsMerged == true)
                                {
                                    int rowSpan = 1;
                                    int colSpan = 1;

                                    for (int i = r + 1; i < table.Rows.Count && table.Cells[i, c].IsMerged == true; i++)
                                    {
                                        rowSpan++;
                                    }

                                    for (int j = c + 1; j < table.Columns.Count && table.Cells[r, j].IsMerged == true; j++)
                                    {
                                        colSpan++;
                                    }

                                    for (int i = r; i < r + rowSpan; i++)
                                    {
                                        for (int j = c; j < c + colSpan; j++)
                                        {
                                            processedCells.Add($"{i},{j}");
                                        }
                                    }

                                    tableContents.Add(new CellData
                                    {
                                        Row = r + 1,
                                        Column = c + 1,
                                        Text = cell.TextString,
                                        RowSpan = rowSpan,
                                        ColumnSpan = colSpan
                                    });
                                }
                                else
                                {
                                    tableContents.Add(new CellData
                                    {
                                        Row = r + 1,
                                        Column = c + 1,
                                        Text = cell.TextString,
                                        RowSpan = 1,
                                        ColumnSpan = 1
                                    });
                                }
                            }
                        }
                    }

                    tr.Commit();
                }
            }

            return tableContents;
        }

        /// <summary>
        /// 只有第一列跨列
        /// </summary>
        public List<List<string>> ExtractTableContents()
        {
            List<List<string>> tableContents = new List<List<string>>();

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a table: ");
            peo.SetRejectMessage("\nSelected entity is not a table.");
            peo.AddAllowedClass(typeof(Table), true);

            PromptEntityResult per = ed.GetEntity(peo);

            if (per.Status == PromptStatus.OK)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Table table = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Table;

                    if (table != null)
                    {
                        for (int r = 0; r < table.Rows.Count; r++)
                        {
                            List<string> rowContents = new List<string>();

                            for (int c = 0; c < table.Columns.Count; c++)
                            {
                                Cell cell = table.Cells[r, c];
                                rowContents.Add(cell.TextString);
                            }

                            tableContents.Add(rowContents);
                        }
                    }

                    tr.Commit();
                }
            }

            return tableContents;
        }
    }

    public class CellData
    {
        public int Row { get; set; }
        public int Column { get; set; }
        public string Text { get; set; }
        public int RowSpan { get; set; }
        public int ColumnSpan { get; set; }
    }

    public class ExcelExporter
    {
        public void ExportToExcel_AutoMerge(List<CellData> tableContents, string filePath)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (ExcelPackage package = new ExcelPackage())
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Sheet1");

                foreach (var cellData in tableContents)
                {
                    if (cellData.RowSpan > 1 || cellData.ColumnSpan > 1)
                    {
                        worksheet.Cells[cellData.Row, cellData.Column, cellData.Row + cellData.RowSpan - 1, cellData.Column + cellData.ColumnSpan - 1].Merge = true;
                    }
                    worksheet.Cells[cellData.Row, cellData.Column].Value = cellData.Text;
                }

                FileInfo file = new FileInfo(filePath);
                package.SaveAs(file);
            }
        }

        public void ExportToExcel(List<List<string>> tableContents, string filePath)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (ExcelPackage package = new ExcelPackage())
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Sheet1");

                // 将第一行的5个单元格合并
                if (tableContents.Count > 0 && tableContents[0].Count >= 5)
                {
                    worksheet.Cells[1, 1, 1, 5].Merge = true;
                    worksheet.Cells[1, 1].Value = tableContents[0][0];
                }

                for (int r = 1; r < tableContents.Count; r++)
                {
                    for (int c = 0; c < tableContents[r].Count; c++)
                    {
                        worksheet.Cells[r + 1, c + 1].Value = tableContents[r][c];
                    }
                }

                FileInfo file = new FileInfo(filePath);
                package.SaveAs(file);
            }
        }
    }



}
